\documentclass{article}
\usepackage{url}

\textheight 21 cm
\textwidth 14 cm
 
\topmargin -1mm
\marginparwidth 0mm
\evensidemargin 1.5 cm
\oddsidemargin 1.5 cm

\begin{document}
\pagestyle{plain}

\bibliographystyle{abbrv}

%\newtheorem{df}{Definition}
%\newtheorem{th}{Theorem}

\title{
\Huge
BinProlog 11.x Professional Edition\\
Internet Programming Guide
\vskip 5cm
}

\author{
\Large
  {\bf Paul Tarau}\\\\
\large
  BinNet Corp.\\
  WWW: http://www.binnetcorp.com
\normalsize
}


%\date{}

\vskip 5cm
\maketitle

\newpage

\section{Introduction}

BinProlog has evolved during the last years towards a sophisticated Logic Programming
based Internet application building tool.
This document covers, through examples, a number of typical Internet programming
patterns.


\section{Installing the BinNet Internet Toolkit}

The default assumptions hold for a Windows machine, but adapting
to Unix is mostly changing some path information.

Just uncompress the file bp\_inet.zip, containing the toolkits you have ordered
to a directory bp\_inet. The resulting directories are as follows:

\begin{itemize}
\item {\bf bin}: BinProlog binary executable (i.e. bp.exe)
\item {\bf cgi}: CGI scripts
\item {\bf library}: shared files, needed for various components
\item {\bf client}: HTTP Client Toolkit
\item {\bf server}: HTTP Server Toolkit
\item {\bf spider}: BinNet Internet Search Engine
\item {\bf tests}: Tests - trying out various components
\end{itemize}


\section{The BinNet Internet Client Library}

CGI programs are executed on the server upon
clicking on special links. They are used from froms for electronic shopping
to online conference organizing.

\subsection{Programming CGIs: the easy way}

To run the CGI scripts securely (assuming http://localhost as the base address)
configure your Web server to have bp\_inet/bin executable only and bp\_inet/cgi
readable only.

The directory structure is configured in such a way, that if you add
your own new scripts let's say somewhere in bp\_inet/myscripts and follow
the same include convention as scripts in directory {\bf cgi}, everything
will run fine.

BinProlog  has some built-in facilities which make CGI-programming
easy. The following shows a simple Web page access counter.

{\small \begin{verbatim}
main:-header,inc(X),show_counter(X).

header:-
  write('220 ok'),nl,
  write('content-type: text/html'),nl,nl.

show_counter(X):-write(counter(X)),write('.'),nl.

inc(X):-
  F='cstate.pro',
  ( see_or_fail(F)-> see(F),read(counter(X)),seen
  ; X=0
  ),X1 is X+1,
  tell(F),show_counter(X1),told.
\end{verbatim}}

To install a similar CGI script at your site, put the {\bf bp} executable
in directory {\bf cgi-bin}, together with the program and call it from
a HTML page as follows:

{\small
\begin{verbatim}
<TITLE>
 BinProlog CGI counter
</TITLE>
<HTML>
<BODY>
Try a BinProlog based
<A HREF=
  "/bp_inet/bin/bp.exe?$/bp_inet/cgi/counter.pro">
CGI Web-counter!        ^^^^^^^^^^^^ 
</A>                   ABSOLUTE PATH!
</BODY>
</HTML>
\end{verbatim}
}

You can try it out by following the demo link at:

{\small
\begin{verbatim}
   http://www.binnetcorp.com/BinProlog
\end{verbatim}
}

Look for LogiMOO \cite{lpnet96:virtual,DPT96:PAP}, a more advanced BinProlog based Internet application, now also running directly under Netscape, at:
{\small
\begin{verbatim}
   http://clement.info.umoncton.ca/~tarau/logimoo
\end{verbatim}
}

\subsubsection{A BinProlog Query Evaluator}
A more complex script (see files cgi/query.pro and cgi/query.html) needs to
be used to pass information from a HTML file to the Prolog script.
BinProlog's cgi\_lib.pro library uses POST method for sending information
to the server. This means, that after some basic header exchange, the client
will read and parse from the standard input field names/field data pairs.
This is achieved by components in cgi\_lib.pro, the script itself 
matches the expected parameters and proceeds with its specific tasks.

{\small \begin{verbatim}
CGI script for querying BinProlog over the net
% Copyright (C) BinNet Corp. 1998

:-['../library/cgi_lib'].
:-['../library/http_tools'].

main:-run_cgi(5,body).

% POST method body
body:-
  (get_cgi_input(Alist)->true;test,fail),
  Alist=
    [ login=Ls,
      passwd=Ps,
      email=Ms,
      home=Hs,
      query=Qs,
      editor=Es
   ]
->
  ( run_it(Ls,Ps,Ms,Hs,Qs,Es)->true
  ; write('Error in query: '),write_chars(Qs),nl
  )
; ( write('Non matching fields in form'),
    fail
  ; nl
  ).
\end{verbatim}}

\subsubsection{A multi-threaded benchmark}

This CGI offers some control over the number of threads to be used
as well as the number of iteration and data size. 

\subsubsection{A Joke Server}

This CGI implements a joke server together with an operation to add
new jokes. The database is implemented as a Prolog file. Additions
occur simply bay concatenation to the end of the file.

\subsubsection{A Guestbook script}

This simple script reads information provided by visitors of
a Web page and appends it in the form of Prolog facts at the end
of a file.

\subsection{A multi-threaded stock market simulator script}

This simple, hand-built form (most other forms are built with HTML generators
like Netscape's Composer) calls the script {\bf smarket.pro}. The script 
was originally written for Jinni - our Java based interpreter - and
actually runs under Jinni as well.

It simulaties a stock ticker and two trading agents - performing some 
typical transactions, triggered by price changes. This is an example
of complex, event driven CGI script, with BinProlog's Linda
blackboard used for multi-agent synchronization.

{\small \begin{verbatim}
<html>

<head>
<title>BinProlog CGI form script</title>
</head>

<body>

<form method="post" 
 target="answer" 
 action="/bp_inet/bin/bp.exe?$/bp_inet/cgi/smarket.pro"> 

<b>Simulation time in seconds:</b> 
   <input name="time" type="text" size="2" value="3">
<b>Variation:</b> 
   <input name="variation" type="text" size="4" value="0.09">
<b>Direction:</b> 
   <input name="direction" size="4" type="text" value="0.001">
<p>
Feel free to add your comments related to this program and BinProlog.
</p>
<textarea align="top" name="comment" rows=3 cols=60>
</textarea>
<input align="bottom" type="submit" value="Submit">
</form>

</body>
</html>
\end{verbatim}}

\subsection{The BinNet HTTP Client}

 The BinNet HTTP Client library supports HTTP 1.x processing
 directly in Prolog, using BinProlog's portable socket operations.
 It allows a BinProlog program to get HTML or ASCII text pages
 from a Web server and "datamine" for links found in the page. 
 It also allows consulting BinProlog files directly from Web pages.
 This library, easy to extend and reuse is provided in source form.
 It interoperates with the BinNet HTTP server and the BinNet Programmable 
 Internet Search Engine (spider).


\begin{itemize}
\item {\bf reconsult\_url(AtomicURL)}:
  reconsults a Prolog file from a Web server i.e. replaces each
  predicate with a new definition found there, asserted to the current
  database

\item {\bf consult\_url(AtomicURL)}:
  consults a Prolog file from a Web server i.e. asserts each
  to the current database


\item {\bf http2line(AtomicURL,Line)}: Opens a URL, then gets a stream of lines
  of chars from the WWW server. It will backtrack over them. At the end,
  it fails. A query, for
\begin{verbatim}
  AtomicURL='http://www.binnecorp.com/test.txt'
\end{verbatim}

pointing to the a file containing the lines:

\begin{verbatim}
  This
  is
  a test.
\end{verbatim}

will work as follow:

\begin{verbatim}
?-http2line('http://www.binnecorp.com/test.txt',Line).
....
....  % some header lines
....
Line=[84,104,105,115];

Line=[105,115];

Line=[97,32,116,101,115,116,46];
no
\end{verbatim}

This acts like if you used 

\begin{verbatim}
 ?-File=[   "This","is","a test."],member(Line,File).
\end{verbatim}

Use name/2 to convert each list of characters returned by Line
to an atom. Type help(read), help(write), help(chars) for
hints on various operations you can perform on each line.

\item {\bf http2line(AtomicURL,Cs)}:
 Same as http2line, but skips header lines.

\item {\bf http2content\_line(AtomicURL,Cs)}: 
extracts the content of html or ascii text page, Prolog code in particular,
to a list of charaters, headers excluded.

\item {\bf http2link(AtomicURL,Link)}: Extracts links to other URLs, found in a HTML page,
  given through its URL.
\begin{verbatim}
  Try:

  ?-http2link('http://www.binnetcorp.com',Link).
\end{verbatim}


\item {\bf http2char(AtomicURL,C)}:
  extracts content of html or ascii text page, Prolog code in particular,
  one character at at time, header excluded.
  Backtracks over each character, fails at end of the stream.
\begin{verbatim}
  Try:

  ?-http2char('http://www.binnetcorp.com/test.txt',C),put_code(C),fail;nl.
\end{verbatim}


\item {\bf http2chars(AtomicURL,Cs)}: extracts content of html or ascii text page, Prolog code in particular,
to a list of characters.

\item {\bf http2clause(AtomicURL,Clause)}:  Extract on clause at a time, from a URL pointing to a Prolog file.
  Backtracks over them, fails at the end. 

\item {\bf http2db(AtomicURL)}:  consults a URL containing Prolog code to current database


\item {\bf http2db(AtomicURL,Db)}:  consults a URL containing Prolog code to a given database

\item {\bf http2db\_replace(AtomicURL)}:  reconsults a URL containing Prolog code to current database,
  while replacing existing predicates having the same signature

\item {\bf assume\_url(AtomicURL)}: assumes with assumei/1, all Prolog clauses at URL

\end{itemize}


\section{The BinNet Internet Search Engine}

The search engine is composed of a kernel library (file http\_spider.pl)
and a set of scripts (http\_spider\_scripts.pl).
The spider remembers links followed. Links can be seen, after executions
with {\tt show\_links}, together with the depth where they are found.

The main interface to the kernel is provided through the predicate
spider/4.

\begin{verbatim}
spider(K,AtomicRoot,Link,Path):

% Walks through links up to depth K
% starting from AtomicRoot of the form 'http://...'
% Returns each Link and Path (a list of canonical links) used to get there.
\end{verbatim}

Keyword search scripts are programmed by extracting list of words,
found on each line of the HTML or text file to which the link refers,
with {\tt http2words(Link,Ws)}.

Good/bad link classification scripts are programmed using
{\tt is\_good\_link(AtomicURL,YesNoMaybe)} which returns yes/no/maybe
depending on valid syntax and actual responsiveness of the URL to
which the link points on the Internet.

To scripts limited to links local to the Web site given as RootURL
are programmed by overriding internal components of the kernel spider
using intuitionistic implication (assumptions), as in:

\begin{verbatim}
/* 
% Internal Spider: moves only inside the domain of TopURL
*/
internal_spider(Depth,TopURL,HarvestedLink):-
  url_filter(internal_only)=>>spider(Depth,TopURL,HarvestedLink).
\end{verbatim}

A number of script examples are given in file {\tt http\_spider\_script.pl}.
The features described can be combined independently, and it is
also possible to start the spider with a meta-search root, for instance,
a Lycos or Yahoo query, which is further explored as if it were an ordinary
html file.

Various tests for the spider as well as of its component
are available in file {\tt bp\_inet/test/http\_test.pl}

\section{The BinNet Web Server}

The server implements a subset of the HTTP 1.x protocol (handling of text/html
files together with efficent execution of Prolog server side includes (SSIs) - scripts
running much more efficiently that dynamicaly loaded CGI scripts - as they are
part of the server. Other requests are redirec by the server to  a standard
server (assumed on the same machine, at port 80). Our server itself,
listens by default on port 8080.

To try out the server, together with a server side include
script handling facility, type

\begin{verbatim}
   bp http_query
\end{verbatim}

Assuming that the BinProlog Internet tools have been
uncompressed in something like \verb~c:\bp_inet~,
just open with Netscape the following link:

\begin{verbatim}
http://localhost:8080/bp_inet/cgi/http_query.html
\end{verbatim}

Click on the {\bf submit} button to see the server interacting
with the Netscape client, both for fetching a file and
running a CGI script-like {\em server side include - (SSI)} program
(based on code in ssi\_lib.pl and http\_query.pl).

This demo form can be easily adapted to remotely
administer the server, with appropriate password
protected queries.

To launch the server only, on default port 8080,
without the SSI facilities, type in a command window:

\begin{verbatim}
   bp http_server
\end{verbatim}

then, type at the prompt:

\begin{verbatim}
?- http_server.
\end{verbatim}

To create distributable bytecode application type:

\begin{verbatim}
bp

?-fcompile(http_query).
\end{verbatim}

Then, run the bytcode application with

\begin{verbatim}
   bp http_query.wam
\end{verbatim}

Note that on platforms where multi-threading is available,
the server spawns new threads for each client.
The script http\_query.pl gives an example of a truly
{\em multi-user} Prolog process: users entering different logins
in the Web form will be assigned different clause databases as well.
Threads/engines spawned to support user requests are recycled after
each execution.


\section{BinProlog Networking}

\subsection{Client/server programming in BinProlog: a first look}

To try this out, open 3 windows, start BinProlog in each, then type:

\begin{verbatim}
   ?-run_server.             % in the first window
   ?-out(hello(your_name)).  % in the second window
   ?-all(X,Xs).              % in the third window
\end{verbatim}

You will see that they are connected! The following sections
will show how this kind of communication is achieved between
your computer and, if you are `wired', other computers over the net.


\section{Mobile Code}

The latest version of BinProlog supports two simple {\bf move/0} and {\bf return/0}
operations which transport
computation to the server and back. 
The client simply waits until computation completes, when bindings
 for the first solution are propagated back:

{\small \begin{verbatim}
Window 1: a mobile thread 

?-there,move,println(on_server),member(X,[1,2,3]),
        return,println(back). 
back
X=1; 
no. 

Window 2: a server 

?-trust. 
on_server 
\end{verbatim}}

In case return is absent, computation proceeds to the end of the transported continuation.
Note that mobile computation is more expressive and more efficient than remote predicate calls as such. Basically, it {\em moves once}, and executes on the server {\em all future computations} of the current AND branch until a return instruction is hit,
when it takes the remaining continuation and comes back. This can be seen by comparing real time execution speed for: 

{\small \begin{verbatim}
?-there,for(I,1,1000),run(println(I)),fail. 

?-there,move,for(I,1,1000),println(I),fail. 
\end{verbatim}}
 
While the first query uses {\tt run/1} each time to send a remote task to the server,
the second moves once the full computation to the server where it executes without
further requiring network communications.
Note that the {\tt move/0, return/0} pair cut nondeterminism for the transported segment
of the current continuation. This avoids having to transport state of the choice-point stack
as well as implementation complexity of multiple answer returns and tedious 
distributed backtracking synchronization. Surprisingly, this is not a strong limitation,
as the programmer can simply use something like:

{\small \begin{verbatim}
?-there,move,findall(X,for(I,1,1000),Xs),return,member(X,Xs).
\end{verbatim}}

\noindent to emulate (finite!) nondeterministic remote execution, by collecting all solutions
at the remote side and exploring them through (much more efficient) local
backtracking after returning.


\section{Threads}

Windows 95/98/NT versions of BinProlog also support multithreaded execution.
Type help(thread), then use info/1 for more information on thread related operations.

In fact, for most programs just using

{\small \begin{verbatim}
bg(Goal)

and

synchronize(Statement)
\end{verbatim}}

are all you need to get started.
Take a look at the StockMarket Web-based demo at
\begin{verbatim}
http://www.binnetcorp.com 
\end{verbatim}

for a more interesting example using multiple threads.


\section{The Web of BinProlog users}

You can get connected to users of BinProlog over the Internet
by opening two windows and starting BinProlog in them
(this should work on an Internet connected Unix or Windows 95/NT
machine).

In the first window type:

\begin{verbatim}
?-host('your.full.internet.address')=>run_server.
\end{verbatim}

In the second window type:

\begin{verbatim}
?-chat.
TARGET SERVERS ALIVE ON THE NET:
..............................
..............................
^D on Unix or ^Z on PCs to end
>
> TYPE IN YOUR MESSAGES HERE!!!
>
\end{verbatim}

Whatever you type in the second window (as well as whatever comes
form other users over the net) can be seen in the first one.

Starting {\tt run\_server} is a fairly secure operation, the (restricted)
server will only accept messages to be displayed and Linda operations.

You can personalize your character (the login name appears
on the screen of other users preceding what you say) with:

\begin{verbatim}
?-login(joe)=>password(evrika)=>chat.
\end{verbatim}

If you cannot connect to a master server or you want to keep
the chat local to your computer you can start a server with
\begin{verbatim}
?-run_server.
\end{verbatim}

\noindent one servant for each user with:
\begin{verbatim}
?-run_servant.
\end{verbatim}

To participate to the local chat do something like:
\begin{verbatim}
?-login(joe)=>talk.
\end{verbatim}

\noindent This will show what you say with prompt {\tt joe} on
the server and all its `satellite' servants.

\subsection{High-level socket operations}

We have tried to hide socket operation as well as possible from
the Prolog programmer, usually interested in elegant, high-level
programming. Some inspiration from Java's approach to socket
programming is gratefully acknowledged.

\begin{itemize}
\item
new\_client(Host,Port,ClientSocket) creates ClientSocket connected to
Host (a remote computer's Internet address, by default localhost), 
Port (a Unix port, by default 9001)
\item new\_server(Port,ServerSocket) opens on Port (by default 9001)
a new ServerSocket
\item new\_service(ServerSocket, Timeout, ServiceSocket)
creates a ServiceSocket answering ServerSocket within Timeout seconds 
\item close\_socket(Socket) closes a server, service or client socket
\item sock\_read(Socket,CharList) reads a list of characters from a
socket. Internally, the length in bytes is sent as 32 bit network-ordered
word is read, then the bytes which are converted to a Prolog list
of character codes.
\item sock\_readln(Socket,CharList) reads a list of characters from a socket, allowing the programmer to internalize it with name/2. Note that
internalizing is better to be avoided as it fills internal tables
which are garbage collected only when restart/0 resets them together
with all dynamic data. However, term\_chars/2 allows extracting
a term from such a list of chars without internalizing it.
\item sock\_write writes a list of characters
to a socket, first its length in bytes then as a sequence of bytes.
\item sock\_writeln writes a list of characters
to a socket, terminated with a newline character. Both sock\_read(ln) and
sock\_write(ln) are intended to be used in `connectionless' ask/answer
style dialog between a client and a server (see the Linda package in file extra.pl built on top of them as an example of use.
\item sleep(N) waits N seconds without using CPU resources
\item fork(Pid) starts a new completely IO-less background Unix process (child) with stdio, stdout and stderr redirected to /dev/null and returns
the child's Pid to the parent and Pid=0 to the child
\end{itemize}

\subsection{Client/server programming: Linda operations}

% extra.pl - Linda operations

\begin{itemize}

\item run\_server/0 runs a foreground Linda server

\item fork\_server/0 runs background Linda server
\item fork\_server/1 forks Linda server and returns its Pid

\item stop\_server/0 stops Linda server
\item stop\_server/1 stops Linda server with given password

\item ask\_server/2 sends a query and gets an answer from Linda server

\item server\_info/1 gets language, host and port info from Linda server
\item serve\_answer/2 is the basic query/answer `interactor' on Linda server. It is applied with call/N to to an input from a client,
to produce an output to be sent back (see file extra.pl for details).

\item out/1 puts a term on Linda server
\item in/1 waits to remove a term from Linda server
\item all/2 gets the list of terms matching arg 1 from Linda server
\item rd/1 reads a terms matching arg 1 from Linda server
\item cin/1 tries to remove a term from Linda server
\item default\_host/1 returns default host for Linda server
\item default\_port/1 returns default port for Linda server. Use
something like host( 'eve.info.umoncton.ca' ) $\Rightarrow$ port(8888) $\Rightarrow$ LindaOperation to `redirect' a Linda operation to work with the specified
host/port. This use of intuitionistic implication
$\Rightarrow$ avoids passing useless parameters
to deep calls. Therefore, multiple versions of the same
predicate with explicit host/port arguments are not needed
for the various Linda operations. Once the host/port are
assumed using $\Rightarrow$, their values are used inside
the proof (execution) of LindaOperation. As  $\Rightarrow$ is
scoped and backtrackable, no unpleasant side-effects remain
after its use, allowing seamless `multiple-server' dialog.
\end{itemize}

Some other operations fix the current host/port/remote code file
on the server, making reference to them simpler in case
we are repeatedly interacting with the same remote server.

\begin{itemize}
\item set\_host/1 sets IP address or name of server host we want to talk to
\item set\_port/1 sets port number of the server we want to talk to
\item set\_code/1 sets the name of the default file/database on remote server, used for instance in remote code fetching (see rload/1).

\end{itemize}

\section{Running remote code}

On an Intranet of trusted users and computers, or in different
windows of your unconnected PC or workstation you might want 
to experiment with a server allowing arbitrary Prolog command
execution. You can start a local remote predicate call server
by typing in a first window:

\begin{verbatim}
?-run_unrestricted_server.
\end{verbatim}

BinProlog's convention is that if the name returned by default\_host/1
is different from {\tt localhost} it assumes you want to get connected
and interoperate through customized servers with other computers using BinProlog.

To override this default setting you can use either
{\tt set\_host('my.full.internet.address')} or
temporarily override your default host by assuming it as a {\tt host/1}
fact with
BinProlog's intuitionistic assumption. Such assumptions are scoped and
forgotten on backtracking,

With

\begin{verbatim}
?-server_host('my.full.internet.address')=>run_server.
\end{verbatim}

By default such servers are registered
on a master server at BinProlog's home,
see {\tt default\_master\_server/1} for its
host/port information.

You can try out your server in a client window with

\begin{verbatim}
?-remote_run((write(hello),nl)).
\end{verbatim}

Note that registered servers are in principle accessible
to other users and therefore {\em not} fully secure, unless
you use one of the following two methods to implement security.

\subsection{A first approach to security: servers with restricted interactors}

Here is the code of the chat server:

\begin{verbatim}
chat_server_interactor(mes(From,Cs),Answer):-show_mes(From,Cs,Answer).
chat_server_interactor(ping(T),R):-term_server_interactor(ping(T),R).
chat_server_interactor(run(_),no).
chat_server_interactor(run(_,_),no).

chat_server:-
  server_interactor(chat_server_interactor)=>>
  run_server.
\end{verbatim}

Basically, by overriding the default 
{\tt server\_interactor} with our {\tt chat\_server\_interactor}
we tell to {\tt chat\_server} that only commands matching
known, secure operations has to be performed on behalf
of remote users.

This might look very simple but some of BinProlog's key
features (intuitionistic implication and higher-order
call/N) are used inside the `generic' server code (see file extra.pl)
to achieve this form of `configurability'.

Here is some {\em interactor} code (which might change in the future) for
two other `secure' servers.


The first one (BinProlog's default) 
is a Linda+chat server (to be started with {\tt run\_server/0}).
It offers an good combination of security and convenience:
only allows modifying its dynamic database remotely through
Linda operations and displaying
messages. It can be shut down remotely (with password)
and checked if alive
and although it can be subject to resource attacks
by malicious users it can do no harm to your files
system or give away information about your computer.

\begin{verbatim}
term_server_interactor(cin(X),R):-serve_cin(X,R).
term_server_interactor(out(X),R):-serve_out(X,R).
term_server_interactor(cout(X),R):-serve_cout(X,R).
term_server_interactor(rd(X),R):-serve_rd(X,R).
term_server_interactor(all(X),Xs):-serve_facts(X,X,Xs).
term_server_interactor(all(X,G),Xs):-serve_facts(X,G,Xs).
term_server_interactor(id(R),R):-this_id(R).
term_server_interactor(ping(T),T):-ctime(T).
term_server_interactor(stop(W),yes):-assumel(server_done(W)).
term_server_interactor(halt(X),R):-serve_halt(X,R).
term_server_interactor(add_servant(X),R):-serve_add_servant(X,R).
term_server_interactor(mes(From,Cs),Answer):-
  show_mes(From,Cs,Answer),
  forward_to_servants(mes(From,Cs)).
term_server_interactor(proxy(H,P,Q),R):-
  ask_a_server(H,P,Q,A)->R=A;R=no.
term_server_interactor(in(X),R):-serve_cin(X,R). % $$thish should block!!!
\end{verbatim}

Note that this interactor even supports proxy forwarding
to a give host/port as well as forwarding
to passive pseudo-servers (called `servants', which
work by watching for given patterns on real servers
and reacting back)
and in particular to the Java applets in related package
LindaInteractor.tar.gz.
Note that the secure execution
of forwarded queries are the responsibility of the 
proxy target.

\subsection{A second approach to security: starting an
Intranet specific master server}

Keeping one's host/port information secret from other users
can be achieved by starting a master server local to a secure
physical or virtual Intranet.

For users behind a firewall, this might actually be the only
way to try out these operations as the default master server
might be unreachable.

To start your own master server type in a window something like:

\begin{verbatim}
?- master_server('my.secure.local.computer',7788)=>run_master_server.
\end{verbatim}

Use a fact
\begin{verbatim}
   master_server('my.secure.local.computer',7788).
\end{verbatim}

Type in or have your code execute:

\begin{verbatim}
  set_master_server('my.secure.local.computer',7788)
\end{verbatim}

in both your client and server programs intended to be
managed by your own master server.

A useful application to this is to build a local chat line
not seen by users from the outside.

Progressively, commercial quality security will be built in BinProlog,
especially if nonsensical export restrictions in US and Canada will be
removed on strong cryptography.

To keep the workload of the master server minimal, only when
an error is detected by a client, the master\_server is asked
to refresh its information and possibly remove dead servers
from its database.

\subsection{Towards a Web of interacting secure mobile agents}

The MOO metaphor combined with the idea of `negotiation' between
the agent's intentions and the `structure of the world', represented
as a set of Linda blackboards storing state information
on servers connected over the the Internet allows a simple and secure
remote execution mechanism through specialized server-side interpreters.

Implementation of arbitrary remote execution is easy
in a Linda + Prolog system due to Prolog's metaprogramming
abilities. No complex serialization remote procedure/method
call packages are needed. In BinProlog (starting with free version 6.25)
code fetched lazily over
the network is cached in a local database and then
dynamically recompiled on the fly if usage statistics
indicate that it is not volatile and it is heavily used locally.

As an example, high performance file-transfer (actually known to be faster than
well-known {\tt http} as {\tt ftp} protocols) is implemented by orchestrating
Prolog based {\tt remote\_run} control operations which are
used to trigger direct full speed transfers entirely left
to optimized C built-ins like {\tt sock2file/2}:

\begin{verbatim}
fget(RemoteFile,LocalFile):-
   remote_run(RF,fopen(RemoteFile,'rb',RF)),
   fopen(LocalFile,'wb',LF),
   term_chars(to_sock(RF),Cmd),
   new_client(Socket),
     sock_write(Socket,Cmd),
     socket(Socket)=>from_sock(LF,_),
     fclose(LF),
     sock_read(Socket,_),
   close_socket(Socket),
   remote_run(fclose(RF)).

from_sock(F,yes):-
   assumed(socket(S)),
   sock2file(S,F),!.
\end{verbatim}

Once the basic Linda protocol is in place and Prolog terms
are sent through sockets, a command filtering server loop
simply listens and executes the set of `allowed' commands.

Despite Prolog's lack of object oriented features we have implemented
code reuse with intuitionistic assumptions.

For instance, to iterate over the set of servers forming
the receiving end of our `Web of MOOs', after retrieving
the list form a `master servers' which constantly monitors
them making sure that the list reflects login/logout
information, we simply override host/1 and port/1 with
intuitionistic implication:

\begin{verbatim}
ask_all_servers(ListOfServers,Question):-
  member(server_id(_,H,P),ListOfServers),
  host(H)=>port(P)=>ask_a_server(Question,_),
  fail.
ask_all_servers(_,_).
\end{verbatim}

To specialize a generic server into either a master server or a
secure `chat-only' server which merges messages from BinProlog
users world-wide we simply override the filtering step in the 
generic server's main interpreter loop.

Implementing agents `roaming over' a set of
servers is a simple and efficient high-level operation.
First, we get the list of servers from the master server.
Then we iterate through the appropriate remote-call negotiation
with each site. Our agent's behavior is limited through
security and resource limitations of participating interpreters,
each having their own command filtering policies.

In particular, on a chat-only server our roaming agent can only
display a message. If the local interpreter allows gathering
user information than our agent can collect it. If the local
interpreter allows question/answering our agent will actually
interact with the human user through the local server window.

Such mobile agents are seen as `connection brokers' between participating
independent server/client sites. For instance if two sites are
willing to have a private conversation or code exchange they can
do so by simply using the server/port/password information our
agent can help them to exchange.

Note that full metaprogramming combined with source-level mobile-code
have the potential of better security than byte-code level verification
as it happens in Java, as meaningful analysis and verification of
program properties is possible.

\subsection{An overview of some remote operations}

The following operations

\begin{verbatim}
host(Other_machine)=>rload(File).

host(Other_machine)=>code(File)=>TopGoal.

host(Other_machine)=>fetch_remote_operators.
\end{verbatim}

allow fetching remote files/operator definitions {\tt rload/1, fetch\_remote\_operators/0} or
on-demand fetching of a predicate at a time from host/code file
during execution of TopGoal.

\begin{verbatim}
host(Other_machine)=>remote_run(RemoteGoal).

host(Other_machine)=>remote_run(Answer,RemoteGoal).
\end{verbatim}

allow remote predicate calls without/with returned answer
on the calling site.

\begin{verbatim}
host(Other_machine)=>rsh(ShellCommand,CharListAnswer).

host(Other_machine)=>rsh(ShellCommand).
\end{verbatim}

allows using BinProlog to remotely execute shell commands
on a remote machine and collect/print the answers at the
calling site. In particular it allows what Microsoft never 
could/wanted to build in W95 or NT: remote shell commands.
In particular, by starting a BinProlog server on a PC with
W95/NT it is possible to do meaningful work on it remotely
from another W95/NT PC or Unix box.
Note that on machines not supporting pipes rsh is approximated
with rexec which redirects execution to a file, gets it
back and shows it to the user. Note also that
\begin{verbatim}
?-run_unrestricted_server.
\end{verbatim}
should be used on the remote computer to allow these commands.


\section{Interaction with Java Applets.}
BinProlog starting from version 5.40 communicates with
our recently released Java based {\em Linda Interactors}\footnote{available at http://clement.info.umoncton/BinProlog/LindaInteractor.tar.gz
} special purpose trimmed down pure Prolog engines written
in Java which support the same unification based
Linda protocol as BinProlog.
The natural extension was to allow Java applets
to participate to the rest of our `peer-to-peer'
network of BinProlog interactors.
As creating a server component within a Java applet
is impossible due to Java's (ultra)-conservative
security policies we have simply written a receiving-end 
{\em servant} close to our
example in subsection \ref{simple}, which relies on a proxy server
on the site where the applet originates from,
for seamless integration in our world of
peer-to-peer interactors.

Here is the code for a more realistic servant,
multiplexed among multiple servers and usable inside
a Java applet.


{\small \begin{verbatim}
run_servant:-
  default_server_interactor(Interactor),
  this_id(ID),
  out(servant_id(ID)), % registers this servant
  repeat,
    in(query(ServerId,Query)), % waits for a query
    (call(Interactor,Query,Reply)->Answer=Reply;Answer=no),
    % sends back an answer, if needed
    ( ServerId=[]->true % no reply sent to anonymous servers
    ; out(answer(ServerId,Answer))
    ),
  functor(Query,stop,_),  % stops when required
  !,
  in(servant_id(ID)).
\end{verbatim}}

Note the presence of an overridable client-side interactor,
allowing the generic servant code to be easily reused/specialized.
Multiplexing is achieved by having each server's in/1 and out/1
data marked with 
unique {\tt servant\_id/1} records.

To integrate multiple Java applet based clients
in our `Web of Worlds', we use a more complex
forwarding server, also available as equivalent Java
code, to be run as a BinProlog and/or Java daemon\footnote{Alternatively,
BinProlog can be embedded as a server side include in an
Apache server (written in C) while the equivalent Java code 
is easily embeddable in the Java based Jigsaw HTTP server.}
on the same machine as the HTTP server the applet comes from.

{\small \begin{verbatim}
run_forwarding_server:-
  server_interactor(forwarding_server_interactor)=>>
  run_server.

forwarding_server_interactor(mes(From,Cs),R):-!,R=yes,
   forward_to_servants(mes(From,Cs)).
forwarding_server_interactor(Q,A):-
   term_server_interactor(Q,A).

forward_to_servants(Query):-
   clause(servant_id(_),true),
   assert(query([],Query)),
   fail.
forward_to_servants(_).
\end{verbatim}}

Note that the forwarding server has the ability
to interact with multiple servants, in particular
with multiple Java applets.
Starting with version 6.25 this forwarding ability
is built in default BinProlog servers started
with {\tt run\_server}.
Try out the example applet in the corresponding version of
the related Java package Jinn available
from 
\begin{verbatim}
http://www.cs.unt.edu/~tarau/netjinni/Jinni.html
\end{verbatim}
 
\section{Communication behind a firewall}
The simplest way to communicate behind a firewall or in case
of dynamic IP assignement is to
use a servant instead of a server. The servant will
watch a real server with {\tt in/1} operations to perform
commands assigned to it. 
To attach the servant to a server with full Internet access
use the server at BinProlog's home i.e. something like:

\begin{verbatim}
?-host('cs.unt.edu')=>port(7001)=>run_servant.
\end{verbatim}

or your own server on the firewall, if you have an account on it.


\section{Generating VRML through BinProlog CGIs}

The following is a quick description of a VRML generator based on my
ILPS'97 tutorial slides. Try it out its CGI version by following a link
from

\begin{verbatim}
http://www.cs.unt.edu/~tarau
\end{verbatim}

The CGI script dynamcally generate a simple animated VRML 2.0 
landscape with some randomly changing colors.

\subsection{VRML and Prolog: the mappings}

\begin{itemize}
\item  hierarchical space representation + event propagation for animation = VRML 2.0

\item the need for theory: deep isomorphisms between the structure of the
 {\em  SPACE} and the structure of {\em  TRUTH}

\item declarative SPACE representation and TRUTH representation
share the same difficulties w.r.t TIME and change

\item cross-fertilization?
\item as usual: shallow dissimilarities can get in the way:
let's show some shallow similarities \verb~:-)~
\end{itemize}


\subsection{A syntactical mapping: VRML ``is'' Prolog}

\begin{itemize}
\item VRML: hierarchical decomposition of the space in regions
\item Prolog: terms as trees
\item concrete syntaxe: closer to Life or Feature Structures than to Prolog
\begin{itemize}
\item all arguments are named, not positional
\item VRML 2.0 ROUTES are structurally similar to DCGs:
   they are used to {\em  thread} together streams of change
\end{itemize}
\end{itemize}

\subsection{Syntax mapping of some key idioms:}

\begin{verbatim}
Prolog         VRML
-------------------------
  @{  } ===>   {  }
  @[  ] ===>   [  ]
  f(a,b,c) ==> f a b c
  a is b   ==> a 'IS' b
  a=b      ==> a b
------------------------
\end{verbatim}

\noindent key idea: let's allow writting unrestricted VRML code in Prolog!

\subsection{Pseudo VRML in Prolog: a PROTO}
\begin{verbatim}
proto anAppearance @[
   exposedField('SFColor')=color(1,0,0),
   exposedField('MFString')=texture@[]
] 
@{
   'Appearance' @{
       material='Material' @{
         diffuseColor is color
       },
       texture='ImageTexture' @{
         url is texture
       }
    }
}.
\end{verbatim}

\subsection{How it looks in VRML?}
\begin{verbatim}
#VRML V2.0 utf8 
 
PROTO anAppearance 
[ 
  exposedField SFColor color 1 0 0 , 
  exposedField MFString texture [] 
] { 
  Appearance { material 
    Material { diffuseColor IS color } 
    texture ImageTexture { 
      url IS texture 
    } 
  } 
} 
\end{verbatim}

\subsection{Some Prolog Macros}
\begin{verbatim}
shape(Geometry):-
  % based on scoped assumptions (=>) 
  default_color(Color),
  toVrml(
     aShape @{
       geometry(Geometry@{}),
       Color
     }
  ).

sphere:- shape('Sphere').
cone:- shape('Cone').
cylinder:- shape('Cylinder').
box:- shape('Box').
\end{verbatim}

\subsection{Using Prolog macros}
\begin{verbatim}
group @{
  children @[
    `transform(
       translation(0,10,4),scale(2,2,2),rotation(0,0,0,0),
       [`sphere, `cone]
     ),
    `transform(
       translation(5,0,0),scale(1,3,6),rotation(0,1,0,1.5),
       [`box]
     )
  ]
}.
\end{verbatim}


\subsection{From the Translator: (with Assumption Grammars)}
\begin{verbatim}
toVrml(X):-number(X),!,#X.
toVrml(X):-atomic(X),!,#X.
toVrml(A@B):-!,#indent(=),toVrml(A),toVrml(B).
toVrml(A=B):-!,toVrml(A),toVrml(B).
toVrml(A is B):-!,#indent(=),toVrml(A),#'IS',toVrml(B).
toVrml({X}):-!,#'{',#indent(+),toVrml(X),#indent(-),#'}'.
toVrml(`X):-!,X.
toVrml(X):-is_list(X),!,
  #'[',#indent(+),vrml_list(X),#indent(-),#']'.
toVrml(X):-is_conj(X),!,vrml_conj(X).
toVrml(T):-compound(T),#indent(=),vrml_compound(T).
\end{verbatim}

\subsection{What's generated?}
\begin{verbatim}
Group { 
  children [ 
    Transform { 
      translation 0 10 4 scale 2 2 2 rotation 0 0 0 0 
      children [ # aShape is a VRML 2.0 PROTO!
        aShape { geometry Sphere{} color 0.7 0.8 0.8 
        } , 
        aShape { geometry Cone{} color 0.6 0.3 0.9
        } 
      ] 
    } , .....
  ] 
} 
\end{verbatim}


\subsection{Some cross-fertilization opportunities:}
\begin{itemize}
\item trivial but useful: Prolog is a great VRML syntax checker!

\item Prolog as a powerful macro language/static optimizer for VRML

\item Prolog as an AI {\em planner} for complex intelligent
  avatar movement in VRML

\item Prolog as a scripting language: Java and Javascript have little
  structural affinity with VRML which is about TERMS: trees of
  3D object groupings!

\item completely powerless: Javascript
\item unnecessarily complex: Java+EAI
\end{itemize}



\section{Inspecting some BinProlog internals}

{\flushleft You} can generate a kind of intermediate WAM-assembler by

\begin{verbatim}
  ?- compile(asm,[file1,file2,...],'huge_file.asm').
\end{verbatim}

{\flushleft A} convenient way to see interactively the sequence of program
transformations BinProlog is based on is:

\begin{verbatim}
?- asm.
a-->b,c,d.
^D

DEFINITE:
a(A,B) :- 
        b(A,C),
        c(C,D),
        d(D,B).

BINARY:
a(A,B,C) :- 
        b(A,D,c(D,E,d(E,B,C))).

WAM-ASSEMBLER:
clause_? a,3
firstarg_? _/0,6
put_structure d/3,var(4-4/11,1/2)
write_variable put,var(5-5/10,1/2)
write_value put,var(2-2/6,2/2)
write_value put,var(3-3/7,2/2)
put_structure c/3,var(3-8/14,1/2)
write_variable put,var(2-9/13,1/2)
write_value put,var(5-5/10,2/2)
write_value put,var(4-4/11,2/2)
execute_? b,3
\end{verbatim}


\section{LogiMOO}

LogiMOO is a BinProlog based virtual world, usable for collaborative
work or simply online chat. A simple agent, the Notifier is provided
(see file moo.pl in directory LogiMOO).

Still in prototype stage, but working fine. 

See the our PAP'96 paper \cite{DPT96:PAP} for more info.

Here is an example of session (requires Solaris 2.4 or better) playing
with distributed objects (created by "obmaster") and listed by "joe".
You'll need some imagination to reconstitute the exact sequence.
Better, try it out yourself on a Sparc with Solaris!

{\small \begin{verbatim}

---------------------------------------------------------------
Window 1: - wizard (see server.pl)

mbp

?- [server].
.....
?- go.
yes
?- notfier started 
wizard says: Hello 
?- list.
place(lobby) . 
lobby contains wizard . 
yes
?- joe says: Hello 
?- obmaster says: Hello 
?- 

------------------------------------------------------------------
Window 2: - joe: (see joe.pl)

mbp

?- [joe].
...
?- go.
notfier started 
joe says: Hello 
?- yes
?- obmaster says: Hello 
?- list.
place(lobby) . 
lobby contains wizard . 
lobby contains joe . 
lobby contains obmaster . 
ob(object,<:,object) . 
obs(object,:>,object) . 
ob(mammal,<:,object) . 
obs(object,:>,mammal) . 
ob(mammal,legs,4) . 
obs(mammal,>>,legs) . 
ob(dog,<:,mammal) . 
obs(mammal,:>,dog) . 
obs(dog,>>,legs) . 
ob(dog,legs,3) . 
yes

------------------------------------------------------------------
Window 3: - obmaster: (see obmaster.pl and included files)

mbp

?- [obmaster].
...
?- go.
notfier started 
obmaster says: Hello 

 :- 
        object with true.
 :- 
        mammal extends object with (legs := 4,true).
 :- 
        dog extends mammal with (legs := 3,true).

?- bye. 
\end{verbatim}}

\section{Related work}

BinProlog related papers can be found following links from
\begin{verbatim}
    ftp://clement.info.umoncton.ca/~tarau
\end{verbatim}
or following links from 
\begin{verbatim}
    http://www.cs.unt.edu/~tarau
\end{verbatim}

{\flushleft The reader} interested in more information on
Internet Programming with BinProlog and its new Java based component
is refered to the following papers:

\cite{T98:jelia,T98:Jinni,TD98:mobile,TDD98:coord,lm,hawai98,TDBwetice:97,TDBwww:97}
and \cite{TDB:97,RDT97,TDRB97:chi,inap96,lpnet96:virtual1,DPT96:PAP,dbt95a}

Related BinProlog documentation is available at: 
\cite{bp7user,bp7advanced,bp7interface,bp7crossref}.

Slides from an ILPS'97 tutorials on Internet Programming with BinProlog
are available following links from:

\begin{verbatim}
http://www.cs.unt.edu/~tarau
\end{verbatim}

\bibliography{tarau}

\end{document}
